package handler

import (
	"errors"
	"gmfs/core/logger"
	"gmfs/core/storage"
	"gmfs/core/tools/pic"
	"gmfs/core/tools/util"
	"gmfs/core/web/ink"
	"gmfs/core/web/model"
	"io/ioutil"
	"net/http"
)

const filemaxsize = 1024 * 1024 * 80

/**
 * POST 文件上传
 * http://localhost:1323/upload
 */
func Upload(ctx *ink.Context) {
	code, mime, msg, rdm, suffix, err := saveFileFromRequest(ctx)
	if err != nil {
		logger.Errorln(err)
		msg = err.Error()
	}

	JsonInfo(ctx, code, mime, suffix, rdm, msg)
	return
}

/**
 * 代理文件上传
 * http://localhost:1323/proxy.html?uri=http://p5.qhimg.com/dmt/490_350_/t01d49b7191cbc97c11.jpg
 */
func Proxy(ctx *ink.Context) {
	code, mime, msg, rdm, suffix, err := proxyFileFromRequest(ctx)
	if err != nil {
		logger.Errorln(err)
		msg = err.Error()
	}

	JsonInfo(ctx, code, mime, suffix, rdm, msg)
	return
}

/**
 * 保存文件
 */
func saveFileFromRequest(ctx *ink.Context) (string, string, string, string, string, error) {
	logger.Debug("upload Reading.. ")

	//POST 上传文件
	file, h, err := ctx.Request.FormFile("file")
	if err != nil {
		logger.Errorln(err)
		return model.MSG_IMG_READ_ERROR, "", "", "", "", err
	}
	defer file.Close()

	//检查文件后缀
	var fileSuffix = util.FileSuffix(h.Filename)
	if fileSuffix == ".exe" {
		return model.MSG_NOT_SUPPORT, "", "", "", fileSuffix, errors.New("file not support.")
	}

	//判断上传文件大小
	data, _ := ioutil.ReadAll(file)
	code, mime, msg, rdm, err := uploadGridFs(ctx, data, fileSuffix)
	return code, mime, msg, rdm, fileSuffix, err
}

/**
 * 保存文件
 */
func proxyFileFromRequest(ctx *ink.Context) (string, string, string, string, string, error) {
	logger.Debug("upload Reading.. ")

	var uri = ctx.Input()["uri"]
	logger.Debugf("upload proxy uri: %s", uri)

	//检查文件后缀
	var fileSuffix = util.FileSuffix(uri)
	if fileSuffix == ".exe" {
		return model.MSG_NOT_SUPPORT, "", "", "", fileSuffix, errors.New("file not support.")
	}

	//保存图片
	data, err := pic.UrlReaderToByte(uri)
	if err != nil {
		logger.Errorln(err)
		return model.MSG_IMG_READ_ERROR, "", "", "", "", err
	}
	code, mime, msg, rdm, err := uploadGridFs(ctx, data, fileSuffix)
	return code, mime, msg, rdm, fileSuffix, err
}

/**
 * 文件上传至 gridFs
 */
func uploadGridFs(ctx *ink.Context, data []byte, fileSuffix string) (string, string, string, string, error) {

	//文件 MIME
	var mime = http.DetectContentType(data)
	if mime == "text/html; charset=utf-8" {
		return model.MSG_NOT_SUPPORT, mime, "", "", errors.New("file not support")
	}

	//判断文件大小
	if len(data) >= filemaxsize {
		return model.MSG_IMG_LESS_THAN, mime, "", "", errors.New("image less than size")
	}

	//上传至 gridfs
	if util.IsImage(mime) {
		//上传图片
		fileId, rdm, isNude, err := storage.SaveImage(ctx, Connection, data)
		if err != nil {
			logger.Debugln(err)
			return model.MSG_IMG_SAVE_ERROR, mime, "", "", err
		}

		//图片涉黄
		if isNude {
			return model.MSG_IMG_ISNUDE, mime, fileId, rdm, nil
		}

		return model.MSG_SUCCESS, mime, fileId, rdm, nil
	} else {
		//上传文件
		fileId, rdm, err := storage.SaveFile(ctx, Connection, data, fileSuffix, mime)
		if err != nil {
			logger.Debugln(err)
			return model.MSG_IMG_SAVE_ERROR, mime, "", "", err
		}

		return model.MSG_SUCCESS, mime, fileId, rdm, nil
	}
}
